﻿using Docx2Epub.Docx;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Docx2Epub.Epub
{
    class EpubChapterGenerator : WriterBase
    {
        private IEnumerable<DocElement> elements;
        private EPubMetadatas metaDatas;
        private string outputDir;
        private string templateHtml;

        public EpubChapterGenerator(string outputPath, IEnumerable<DocElement> elements, EPubMetadatas metadatas)
        {
            this.outputDir = Path.Combine(outputPath, "OEBPS");
            this.templateHtml = Path.Combine(outputPath, "OEBPS", "chapTEmplate.xhtml");
            this.elements = elements;
            this.metaDatas = metadatas;
        }

        internal void GenerateAll()
        {
            var estack = new Stack<DocElement>(this.elements.SkipWhile(e => !(e is DocChapter)).Reverse());

            while (!(estack.Peek() is DocChapter))
                estack.Pop();

            while (estack.Count > 0)
            {
                var currentChapter = (DocChapter)estack.Pop();
                var chapterHtmlPath = Path.Combine(this.outputDir, currentChapter.FileName);
                XElement doc = XElement.Load(templateHtml);

                buildDoc(doc, currentChapter, estack);

                using (FileStream fs = new FileStream(chapterHtmlPath, FileMode.Create, FileAccess.Write))
                using (StreamWriter sr = new StreamWriter(fs))
                    doc.Save(sr);
            }

            File.Delete(templateHtml);
        }

        private void buildDoc(XElement doc, DocChapter currentChapter, Stack<DocElement> estack)
        {
            // set title
            doc.XPathSelectElement("/xhtml:head/xhtml:title", nsmgr).Value = currentChapter.Title;

            var body = doc.XPathSelectElement("/xhtml:body", nsmgr);
            body.Add(new XElement(xhtml + "h1", new XAttribute("id", currentChapter.ChapterId), currentChapter.Title));

            while (estack.Count != 0 && !(estack.Peek() is DocChapter))
            {
                var next = estack.Pop();
                var section = next as DocSection;
                var paragraph = next as DocParagraph;

                if (section != null)
                    body.Add(new XElement(xhtml + ("h" + section.Level), new XAttribute("id", section.SectionNavigationId), section.Title));
                else
                    body.Add(new XElement(xhtml + "p", paragraph.Body));
            }
        }
    }
}
